From: Florian Müllner Date: Tue, 10 Feb 2026 14:30:46 +0000 (+0100) Subject: layout: Reject promise if background loading is interrupted X-Git-Tag: archive/raspbian/50.5-1+rpi1~1^2~26^2~1^2~20 X-Git-Url: https://dgit.raspbian.org/%22http://www.example.com/cgi/%22/%22http:/www.example.com/cgi/%22?a=commitdiff_plain;h=ac5f521c656d4f88e1b62c2e7e1d610850515ca9;p=gnome-shell.git layout: Reject promise if background loading is interrupted Currently if a background manager is destroyed while we are waiting for the background to load, the corresponding promise never resolves. To prevent this from happening (and the startup animation getting stuck as a result), guard the loading operation with a cancellable and reject the promise when it is cancelled. Closes: https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/9018 Part-of: --- diff --git a/js/ui/layout.js b/js/ui/layout.js index 8f07ac63e..362598d3c 100644 --- a/js/ui/layout.js +++ b/js/ui/layout.js @@ -525,16 +525,25 @@ export const LayoutManager = GObject.registerClass({ } } - _waitLoaded(bgManager) { - return new Promise(resolve => { - const id = bgManager.connect('loaded', () => { - bgManager.disconnect(id); - resolve(); - }); + _waitLoaded(bgManager, cancellable) { + const {promise, resolve, reject} = Promise.withResolvers(); + const cancelId = cancellable.connect(() => { + reject(new GLib.Error(Gio.IOErrorEnum, Gio.IOErrorEnum.CANCELLED, + 'Background loading was cancelled')); + }); + const loadedId = bgManager.connect('loaded', () => { + bgManager.disconnect(loadedId); + cancellable.disconnect(cancelId); + resolve(); }); + + return promise; } _updateBackgrounds() { + this._bgLoadCancellable?.cancel(); + this._bgLoadCancellable = null; + for (let i = 0; i < this._bgManagers.length; i++) this._bgManagers[i].destroy(); @@ -543,6 +552,9 @@ export const LayoutManager = GObject.registerClass({ if (Main.sessionMode.isGreeter) return Promise.resolve(); + const cancellable = new Gio.Cancellable(); + this._bgLoadCancellable = cancellable; + for (let i = 0; i < this.monitors.length; i++) { const bgManager = this._createBackgroundManager(i); this._bgManagers.push(bgManager); @@ -551,7 +563,8 @@ export const LayoutManager = GObject.registerClass({ bgManager.backgroundActor.hide(); } - return Promise.all(this._bgManagers.map(this._waitLoaded)); + return Promise.all( + this._bgManagers.map(mgr => this._waitLoaded(mgr, cancellable))); } _updateKeyboardBox() {